package frog.lazy.framework.keeper.utils;

import cn.hutool.core.util.IdUtil;
import cn.hutool.crypto.SecureUtil;
import cn.hutool.crypto.symmetric.AES;
import frog.lazy.framework.core.exception.BizException;
import frog.lazy.framework.core.tools.StrUtils;
import frog.lazy.framework.keeper.dto.AccountDTO;
import frog.lazy.framework.keeper.dto.JwtTokenDTO;
import io.jsonwebtoken.*;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import javax.annotation.PostConstruct;
import javax.xml.bind.DatatypeConverter;
import java.util.*;

@Component
public class JWTUtils {
    @Value("${token.sign:4QrcOUm6Wau+VuBX8g+IPg==}")
    private String sign;

    @Value("${token.secure:JXU2MjExJXU1QzMx}")
    private String aecKey;

    private AES aes;

    @PostConstruct
    public void init(){
        aes = SecureUtil.aes(SecureUtil.generateKey("AES", aecKey.getBytes()).getEncoded());
    }


    public String getToken(JwtTokenDTO jwtTokenDTO, Long period){
        String encrypted = aes.encryptHex(jwtTokenDTO.getAppId());
        return issueJWT(IdUtil.simpleUUID(),
                encrypted,
                jwtTokenDTO.getPassword(),
                period * 60,
                jwtTokenDTO.getCoordinate(),
                jwtTokenDTO.getIpHost(),
                SignatureAlgorithm.HS512
                );
    }

    private String issueJWT(String id,String appId, String password, Long period, String coordinate, String ipHost,  SignatureAlgorithm algorithm) {
        Long currentTimeMillis = System.currentTimeMillis();
        JwtBuilder jwtBuilder = Jwts.builder();
        if (!StringUtils.isEmpty(id)) {
            jwtBuilder.setId(id);
        }
        if (!StringUtils.isEmpty(appId)) {
            jwtBuilder.setSubject(appId);
        }
        if (!StringUtils.isEmpty(password)) {
            jwtBuilder.claim("password",password);
        }
        jwtBuilder.setIssuedAt(new Date(currentTimeMillis));
        if (null != period) {
            jwtBuilder.setExpiration(new Date(currentTimeMillis+period*1000));
        }
        if (!StringUtils.isEmpty(coordinate)) {
            jwtBuilder.claim("coordinate",coordinate);
        }
        if (!StringUtils.isEmpty(ipHost)) {
            jwtBuilder.claim("ipHost",ipHost);
        }
        jwtBuilder.compressWith(CompressionCodecs.DEFLATE);
        jwtBuilder.signWith(algorithm, sign);
        return  jwtBuilder.compact();
    }


    public AccountDTO parseJwt(String token){
        Claims claims = null;
        String userIdStr = StrUtils.EMPTY;
        try{
            claims = Jwts.parser()
                    .setSigningKey(DatatypeConverter.parseBase64Binary(sign))
                    .parseClaimsJws(token)
                    .getBody();
            userIdStr = aes.decryptStr(claims.getSubject());
        }catch (Exception e) {
            throw BizException.noLogin("用户登录失效");
        }

        return AccountDTO.builder()
                .appId(Long.parseLong(userIdStr))
                .tokenId(claims.getId())
                .password(claims.get("password", String.class))
                .overdue(claims.getExpiration())
                .coordinate(claims.get("coordinate", String.class))
                .ipHost(claims.get("ipHost", String.class))
                .build();
    }



}
